<template>
  <div>
    <el-switch
      v-model="draggable"
      active-text="拖拽开启"
      inactive-text="拖拽关闭">
    </el-switch>
    <el-button v-if="draggable" @click="bathSave()">批量保存</el-button>
    <el-button  @click="bathDelete()">批量删除</el-button>
    <el-tree :data="menus"
             :props="defaultProps"
             :expand-on-click-node="false"
             node-key="catId" show-checkbox
             :default-expanded-keys="expandKeyTree"
             :draggable="draggable"
             :allow-drop="allowDrop"
             @node-drop="handleDrop"
             ref="menuTree"
    >
      <span class="custom-tree-node" slot-scope="{ node, data }">
          <span>{{ node.label }}</span>
          <span>
            <el-button
              v-if="node.level<=2"
              type="text"
              size="mini"
              @click="() => append(data)">
              新增
            </el-button>
            <el-button
              type="text"
              size="mini"
              @click="menuEdit(data)">
              修改
            </el-button>
            <el-button
              v-if="node.childNodes.length==0"
              type="text"
              size="mini"
              @click="() => remove(node, data)">
              删除
            </el-button>
          </span>
        </span>
    </el-tree>
    <el-dialog :title=mentTitle :visible.sync="dialogFormVisible" width="30%" :close-on-click-modal="false">
      <el-form :model="cateMenu" label-width="80px">
        <el-form-item label="菜单名称:">
          <el-input v-model="cateMenu.name"></el-input>
        </el-form-item>
        <el-form-item label="图标:">
          <el-input v-model="cateMenu.icon"></el-input>
        </el-form-item>
        <el-form-item label="计量单位:">
          <el-input v-model="cateMenu.productUnit"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="addMenu()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
    // import Vue from 'vue';
    // import VueResource from 'vue-resource'
    // Vue.use(VueResource)
    // 如果我们通过全局配置了，请求的数据接口 根域名，则 ，在每次单独发起 http 请求的时候，请求的 url 路径，应该以相对路径开头，前面不能带 /  ，否则 不会启用根路径做拼接；
    // Vue.http.options.root = '';
    // 全局启用 emulateJSON 选项
    // Vue.http.options.emulateJSON = true;
    export default {
      name: '',
        // 存放 数据
      data () {
        return {
          pcid: 0,
          menus: [],
          draggable: false,
          mentTitle: '',
          maxLevel: 0,
          updateNodes: [],
          cateMenu: {
            name: '',
            parentCid: null,
            catLevel: 0,
            showStatus: 1,
            sort: 0,
            catId: 0,
            icon: '',
            productUnit: ''
          },
          dialogFormVisible: false,
          defaultProps: {
            children: 'children',
            label: 'name'
          },
          expandKeyTree: []
        }
      },
        // 存放 方法
      methods: {
        clearForm () {
          this.cateMenu = {
            name: '',
            parentCid: null,
            catLevel: 0,
            showStatus: 1,
            sort: 0,
            catId: 0,
            icon: '',
            productUnit: ''
          }
        },
        append (data) {
          this.mentTitle = '新增菜单'
          this.clearForm()
          this.dialogFormVisible = true
          this.cateMenu.catLevel = data.catLevel * 1 + 1
          this.cateMenu.parentCid = data.catId
        },
        addMenu () {
          if (this.mentTitle === '新增菜单') {
            this.$http({
              url: this.$http.adornUrl('/product/category/save'),
              method: 'post',
              data: this.$http.adornData(this.cateMenu, false)
            }).then(({data}) => {
              if (data && data.code === 0) {
                this.$message({
                  message: '新增成功',
                  type: 'success'
                })
                this.dialogFormVisible = false
                this.getMenus()
                this.expandKeyTree = [this.cateMenu.parentCid]
              } else {
              }
            })
          } else if (this.mentTitle === '修改菜单') {
            var data = {catId: 0, name: '', icon: '', productUnit: ''}
            data = this.cateMenu
            this.$http({
              url: this.$http.adornUrl('/product/category/update'),
              method: 'post',
              data: this.$http.adornData(data, false)
            }).then(({data}) => {
              if (data && data.code === 0) {
                this.$message({
                  message: '修改成功',
                  type: 'success'
                })
                this.dialogFormVisible = false
                this.getMenus()
                this.expandKeyTree = [this.cateMenu.parentCid]
              } else {
              }
            })
          }
        },
        menuEdit (data) {
          this.mentTitle = '修改菜单'
          this.dialogFormVisible = true
          this.$http({
            url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
            method: 'get'
          }).then(({data}) => {
            if (data && data.code === 0) {
              this.cateMenu.catId = data.data.catId
              this.cateMenu.name = data.data.name
              this.cateMenu.icon = data.data.icon
              this.cateMenu.productUnit = data.data.productUnit
              this.cateMenu.parentCid = data.data.parentCid
            } else {
            }
          })
        },
        remove (node, data) {
          var ids = [data.catId]
          this.$confirm(`是否删除当前【${data.name}】菜单, 是否继续?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$http({
              url: this.$http.adornUrl('/product/category/delete'),
              method: 'post',
              data: this.$http.adornData(ids, false)
            }).then(({data}) => {
              if (data && data.code === 0) {
                this.$message({
                  message: '删除成功',
                  type: 'success'
                })
                this.expandKeyTree = [node.parent.data.catId]
                this.getMenus()
              } else {
              }
            })
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            })
          })
        },
        getMenus () {
          this.$http({
            url: this.$http.adornUrl('/product/category/list/tree'),
            method: 'get'
          }).then(data => {
            this.menus = data.data.data
          })
        },
        // 拖拽方法
        allowDrop (draggingNode, dropNode, type) {
          this.maxLevel = 0
          // 1. 被拖动的当前节点层数以及父节点的总层数不能大于3
          this.countNodeLevel(draggingNode)
          // 2. 得到子节点的最大层数 - 当前拖动节点的层数 +1 = 整体拖动的当前节点总共有几层
          let deep = Math.abs(this.maxLevel - draggingNode.level) + 1
          if (type === 'inner') {
            return (deep + dropNode.level) <= 3
          } else {
            return (deep + dropNode.parent.level) <= 3
          }
        },
        // 计算当前节点下 子节点的最大深度方法
        countNodeLevel (node) {
          if (node.childNodes != null && node.childNodes.length > 0) {
            for (let i = 0; i < node.childNodes.length; i++) {
              if (node.childNodes[i].level > this.maxLevel) {
                this.maxLevel = node.childNodes[i].level
              }
              this.countNodeLevel(node.childNodes[i])
            }
          }
        },
        // 拖拽成功触发的事件
        handleDrop (draggingNode, dropNode, dropType, ev) {
          // 会发生变化的有如下几个属性
          // 1. 当前节点的 最新的父节点
          let pCid = 0        // 父节点
          let slbling = null // 会发生变化的(目标节点）节点的父节点下的所有子节点
          if (dropType === 'before' || dropType === 'after') {
            pCid = dropNode.parent.data.catId === undefined ? 0 : dropNode.parent.data.catId
            slbling = dropNode.parent.childNodes
          } else {
            pCid = dropNode.data.catId
            slbling = dropNode.childNodes
          }
          // 2. 当前拖拽节点的最新顺序+拖拽节点的 最新层级
          for (let i = 0; i < slbling.length; i++) {
            if (slbling[i].data.catId === draggingNode.data.catId) {
                // 如果遍历的是当前正在推拽的节点--需要另外更改parentCid
              let catLevel = draggingNode.level // 默认的层级
              // 当前的节点发生了层级的变化
              if (slbling[i].level !== draggingNode.level) {
                // 获取最新当前节点的层级
                catLevel = slbling[i].level
                // 修改当前子节点的层级
                this.updateChildNodeLevel(slbling[i])
              }
              this.updateNodes.push({catId: slbling[i].data.catId, sort: i, parentCid: pCid, catLevel: catLevel})
            } else {
              this.updateNodes.push({catId: slbling[i].data.catId, sort: i})
            }
          }
          this.pcid = pCid
          // console.log(this.updateNodes)
        },
        updateChildNodeLevel (node) {
          if (node.childNodes.length > 0) {
            for (let i = 0; i < node.childNodes.length; i++) {
              var cNode = node.childNodes[i].data
              this.updateNodes.push({catId: cNode.catId, catLevel: node.childNodes[i].level})
              this.updateChildNodeLevel(node.childNodes[i])
            }
          }
        },
        bathSave () {
          // 发送数据到后端修改
          this.$http({
            url: this.$http.adornUrl('/product/category/update/sort'),
            method: 'post',
            data: this.$http.adornData(this.updateNodes, false)
          }).then(({data}) => {
            if (data && data.code === 0) {
              this.$message({
                message: '修改菜单排序成功',
                type: 'success'
              })
              this.expandKeyTree = [this.pcid]
              this.getMenus()
              this.maxLevel = 0
              this.updateNodes = []
              this.pcid = 0
            } else {
            }
          })
        },
        bathDelete () {
          let catIds = []
          let catNames = []
          let checkNodes = this.$refs.menuTree.getCheckedNodes()
          for (let i = 0; i < checkNodes.length; i++) {
            catIds.push(checkNodes[i].catId)
            catNames.push(checkNodes[i].name)
          }
          this.$confirm(`是否删除当前【${catNames}】菜单, 是否继续?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$http({
              url: this.$http.adornUrl('/product/category/delete'),
              method: 'post',
              data: this.$http.adornData(catIds, false)
            }).then(({data}) => {
              if (data && data.code === 0) {
                this.$message({
                  message: '删除菜单成功',
                  type: 'success'
                })
                this.getMenus()
              } else {
              }
            })
          })
        }
      },
        // 存放 过滤器
      filters: {},
        // 自定义 私有指令
      directives: {},
        // 存放 子组件
        // template: '',
        // 注意： 组件中的 所有 props 中的数据，都是通过 父组件传递给子组件的
        // props 中的数据，都是只读的，无法重新赋值
        // props: [], // 把父组件传递过来的 parentmsg 属性，先在 props 数组中，定义一下，这样，才能使用这个数据
        /*  生命周期函数  */
        // 创建期间
      beforeCreate () {
      },
      created () {
        this.getMenus()
      },
      beforeMount () {
      },
      mounted () {
      },
        // 运行期间
      beforeUpdate () {
      },
      updated () {
      },
        // 销毁时期
      beforeDestroy () {
      },
      destroyed () {
      }

    }
</script>

<style scoped>
</style>
